home *** CD-ROM | disk | FTP | other *** search
- /*
- MikDLL - Done by MikMak / HaRDCoDE '95
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <dos.h>
- #include <string.h>
- #include "mdllload.h"
-
- typedef unsigned short UWORD;
-
- typedef struct{
- UWORD signature;
- UWORD partpag;
- UWORD pagecnt;
- UWORD relocnt;
- UWORD hdrsize;
- UWORD minmem;
- UWORD maxmem;
- UWORD reloss;
- UWORD exesp;
- UWORD chksum;
- UWORD exeip;
- UWORD relocs;
- UWORD tabloff;
- UWORD overlay;
- } EXEHEADER;
-
- typedef struct EXPORTENTRY{
- struct EXPORTENTRY *next;
- char *name;
- void *obj;
- } EXPORTENTRY;
-
- static char *dll_error=NULL;
- static EXPORTENTRY *pool=NULL;
- static int removeexports=0;
-
-
- static EXPORTENTRY *findexportentry(char *name)
- {
- EXPORTENTRY *e;
-
- e=pool;
-
- while(e!=NULL){
- if(!strcmp(e->name,name)) break;
- e=e->next;
- }
-
- return e;
- }
-
-
- void huge MDLL_Export(char *name,void *obj)
- /*
- MDLL_Export
- ===========
-
- Adds an object (function or a datablock) to the exports-pool so a DLL
- can use that object in the future.
-
- Input:
-
- char *name : The ASCIIZ name of the object to be exported, by
- which it will be registered in the exports-pool.
-
- void *obj : The address of the object to be exported.
-
-
- Returns:
- -
-
- Note:
- This function never fails.. when the EXPORTENTRY can't be allocated,
- it'll simply _not_ add the function to the exports-pool.
-
- Note 2:
- When the static 'removeexports' is true, this function will go in reverse,
- it will remove the objects referenced by 'name' from the exports-pool.
- When a DLL has to be 'unlinked' I simply set removeexports to 1 , and call
- the DLL entry point again; all objects previously exported will be removed
- from the exports-pool.
- */
- {
- EXPORTENTRY *e,*o;
-
- o=findexportentry(name);
-
- if(!removeexports){
-
- if(o!=NULL){
- printf("\n'%s' exported twice.\n",name);
- exit(0);
- }
-
- printf("Exporting %s\n",name);
-
- e=malloc(sizeof(EXPORTENTRY));
-
- if(e==NULL) return;
-
- e->next=NULL;
- e->name=name;
- e->obj=obj;
-
- e->next=pool;
- pool=e;
- }
- else{
- printf("Removing %s from exports-pool\n",name);
-
- e=pool;
- o->name=e->name;
- o->obj=e->obj;
- pool=e->next;
- free(e);
- }
- }
-
-
-
- void * huge MDLL_Import(char *name)
- /*
- MDLL_Import
- ===========
-
- Finds the address of an object by reference of it's name. This routine
- is used by a DLL to access external functions/data.
-
- Input:
-
- char *name : The ASCIIZ name of the object to be imported.
-
-
- Returns:
-
- The address of the object.
-
- Note:
- When the object can't be found, this function will report the failure and
- exit the program.
- */
- {
- EXPORTENTRY *e=findexportentry(name);
-
- if(e==NULL){
- printf("\nCouldn't resolve external reference: '%s'\n",name);
- exit(0);
- }
-
- return e->obj;
- }
-
-
- void *MDLL_entry(MDLL *mp)
- {
- long t;
- char *s=mp->module;
-
- for(t=0;t<mp->modulesize;t++){
- if(!memcmp(s,"MDLLTAG",7) && s[7]=='0'){
- return(((TAG *)s)->func);
- }
- s++;
- }
- return NULL;
- }
-
-
- void MDLL_Unbind(MDLL *mp)
- {
- removeexports=1;
- mp->entryp(MDLL_Import,MDLL_Export);
- removeexports=0;
- free(mp->memblk);
- }
-
-
- int MDLL_Bind(MDLL *mp,char *name)
- {
- FILE *fp;
- EXEHEADER hdr;
- union REGS regs;
- struct SREGS sregs;
-
- struct{
- int envseg;
- int reloc;
- } e;
-
- dll_error="No error";
-
- // open file & read exe header
-
- if((fp=fopen(name,"rb"))==NULL){
- dll_error="Couldn't open MDLL executable";
- return 0;
- }
- fread(&hdr,sizeof(EXEHEADER),1,fp);
- fclose(fp);
-
- mp->modulesize=(512L*hdr.pagecnt)-(16L*hdr.hdrsize);
-
- // allocate memory for overlay
-
- if((mp->memblk=malloc(mp->modulesize+16))==NULL){
- dll_error="MDLL memory block malloc failed, MDLL too big?";
- return 0;
- }
-
- // paragraph align module ptr
-
- mp->module=MK_FP(FP_SEG(mp->memblk)+1,0);
-
- // fill segment registers
-
- segread(&sregs);
-
- e.envseg=FP_SEG(mp->module);
- e.reloc=FP_SEG(mp->module);
-
- regs.h.ah=0x4b; // dos function 'EXEC'
- regs.h.al=0x03; // load overlay
- sregs.ds=FP_SEG(name);
- regs.x.dx=FP_OFF(name);
-
- sregs.es=FP_SEG(&e);
- regs.x.bx=FP_OFF(&e);
-
- intdosx(®s,®s,&sregs);
-
- if(regs.x.cflag!=0){
- free(mp->memblk);
- dll_error="Dos func 0x4b failed";
- return 0;
- }
-
- mp->entryp=MDLL_entry(mp);
-
- if(mp->entryp==NULL){
- free(mp->memblk);
- dll_error="Couldn't find MDLL entrypoint";
- return 0;
- }
-
- mp->entryp(MDLL_Import,MDLL_Export);
- return 1;
- }
-
-
- char *MDLL_Error(void)
- {
- return dll_error;
- }
-